<template>
  <div class="electron-app">
    <div class="opacity-control" :class="{ 'hidden-opacity-control': !showControls }">
      <div v-if="showControls" class="control-panel">
        <div class="form-group">
          <label for="inputUrl">网址</label>
          <div class="url-input-group">
            <div class="navigation-buttons">
              <button class="nav-button" @click="goBack" :disabled="!canGoBack">
                <span>←</span>
              </button>
              <button class="nav-button" @click="goForward" :disabled="!canGoForward">
                <span>→</span>
              </button>
            </div>
            <select v-model="protocol" class="protocol-select">
              <option value="https://">https://</option>
              <option value="http://">http://</option>
            </select>
            <input v-model="inputUrl" class="url-input" placeholder="请输入网址" @keyup.enter="onSo">
            <div class="button-group">
              <button class="primary-button" @click="onSo">前往</button>
              <button class="secondary-button" @click="refreshWebview">刷新</button>
            </div>
          </div>
        </div>

        <div class="form-group">
          <label for="bgcolor">背景颜色</label>
          <div class="color-input-group">
            <input type="color" id="bgcolor" v-model="backgroundColor" class="color-picker">
            <div class="range-input-group">
              <input type="range" id="bgOpacity" min="0" max="1" step="0.01" v-model="backgroundColorOpacity"
                @input="changeBackgroundColor" class="range-slider">
              <span class="range-value">{{ backgroundColorOpacity }}</span>
            </div>
            <button class="primary-button" @click="changeBackgroundColor">设置</button>
            <button class="secondary-button" @click="setTransparent">去除背景色</button>
            <button class="secondary-button" @click="removeAllInjectedCSS">恢复原始</button>
          </div>
        </div>

        <div class="form-group">
          <label for="opacity">透明度</label>
          <div class="range-input-group">
            <input type="range" id="opacity" min="0.1" max="1" step="0.01" v-model="opacity" @input="setOpacity"
              class="range-slider">
            <span class="range-value">{{ opacity }}</span>
          </div>
        </div>

        <div class="form-group">
          <label for="zoom">缩放比例</label>
          <div class="range-input-group">
            <input type="range" id="zoom" min="0.1" max="1" step="0.01" v-model="ZoomFactor" @input="setZoomFactor"
              class="range-slider">
            <span class="range-value">{{ ZoomFactor }}</span>
          </div>
        </div>

        <div class="form-group">
          <label for="useragent">浏览器样式</label>
          <select v-model="useragent" class="browser-select">
            <option
              value="Mozilla/5.0 (Linux; Android 10; SM-G981B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.162 Mobile Safari/537.36">
              手机</option>
            <option
              value="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36">
              电脑</option>
          </select>
        </div>
      </div>
    </div>
    <webview ref="webviewRef" class="ifr" :src="useUrl" plugins nodeintegration allowpopups :useragent="useragent">
    </webview>
  </div>
</template>

<script setup>
import { ref, onMounted, onBeforeUnmount } from "vue";

// ========================================================================================
// 响应式数据定义 (Reactive Data)
// ========================================================================================

/** 
 * 网络相关状态
 */
/** 协议类型 (https:// 或 http://) */
const protocol = ref("https://");
/** 用户代理字符串，用于模拟不同设备 */
const useragent = ref("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36");
/** 用户输入的URL地址 */
const inputUrl = ref("");
/** 实际使用的完整URL地址 */
const useUrl = ref("https://bing.com");

/**
 * WebView相关状态
 */
/** WebView DOM元素引用 */
const webviewRef = ref();
/** 网页缩放比例 */
const ZoomFactor = ref(1);

/**
 * 导航相关状态
 */
/** 是否可以后退 */
const canGoBack = ref(false);
/** 是否可以前进 */
const canGoForward = ref(false);

/**
 * 外观控制相关状态
 */
/** 是否显示控制面板 */
const showControls = ref(true);
/** 窗口透明度 */
const opacity = ref(1);
/** 背景颜色 */
const backgroundColor = ref('transparent');
/** 背景颜色透明度 */
const backgroundColorOpacity = ref(1);
/** 注入的CSS键 */
const injectedCSSKeys = ref(new Set());

// ========================================================================================
// 工具函数 (Utility Functions)
// ========================================================================================

/**
 * 将十六进制颜色转换为RGBA格式
 * @param {string} hex - 十六进制颜色值 (如: #ffffff)
 * @param {number} alpha - 透明度值 (0-1)
 * @returns {string} RGBA颜色字符串
 */
function hexToRgba(hex, alpha) {
  const r = parseInt(hex.slice(1, 3), 16);
  const g = parseInt(hex.slice(3, 5), 16);
  const b = parseInt(hex.slice(5, 7), 16);
  return `rgba(${r}, ${g}, ${b}, ${alpha})`;
}

/**
 * 更新导航按钮状态
 * 检查WebView是否可以前进或后退，并更新对应的状态
 */
function updateNavigationState() {
  const webview = webviewRef.value;
  if (webview) {
    canGoBack.value = webview.canGoBack();
    canGoForward.value = webview.canGoForward();
  }
}

// ========================================================================================
// 背景颜色控制函数 (Background Color Control)
// ========================================================================================

/**
 * 更改WebView页面背景颜色
 * 根据当前选择的颜色和透明度，向页面注入CSS样式
 */
async function changeBackgroundColor() {
  const webview = webviewRef.value;
  if (!webview) return;

  // 根据背景颜色类型计算最终颜色值
  let color;
  if (backgroundColor.value === 'transparent') {
    color = 'transparent';
  } else if (backgroundColor.value === '#ffffff') {
    color = `rgba(255, 255, 255, ${backgroundColorOpacity.value})`;
  } else if (backgroundColor.value === '#000000') {
    color = `rgba(0, 0, 0, ${backgroundColorOpacity.value})`;
  } else {
    color = hexToRgba(backgroundColor.value, backgroundColorOpacity.value);
  }

  // 注入CSS样式到页面
  const cssKey = await webview.insertCSS(`
        * {
          background: ${color} !important;
        }
      `);
  injectedCSSKeys.value.add(cssKey);
}

/**
 * 设置背景为透明
 * 快捷方式，直接将背景设置为透明并应用
 */
function setTransparent() {
  backgroundColor.value = 'transparent';
  changeBackgroundColor();
}

/**
 * 删除所有注入的CSS样式
 * 清除页面中所有包含background样式的style标签
 */
async function removeAllInjectedCSS() {
  const webview = webviewRef.value;
  if (webview) {
    try {
      for (const key of injectedCSSKeys.value) {
        await webview.removeInsertedCSS(key);
      }
      injectedCSSKeys.value.clear();
    } catch (error) {
      console.error("删除CSS时出错:", error);
      // 如果删除失败，清空键值集合
      injectedCSSKeys.value.clear();
    }
  }
}

// ========================================================================================
// 窗口控制函数 (Window Control)
// ========================================================================================

/**
 * 设置窗口透明度
 * 通过IPC通信与主进程交互，设置整个窗口的透明度
 */
async function setOpacity() {
  try {
    const actualOpacity = await window.electron.ipcRenderer.invoke('set-opacity', opacity.value);
    console.log('实际设置的透明度:', actualOpacity);
  } catch (error) {
    console.error('设置透明度失败:', error);
  }
}

// ========================================================================================
// 导航控制函数 (Navigation Control)
// ========================================================================================

/**
 * 导航到指定URL
 * 组合协议和用户输入的URL，然后加载页面
 */
function onSo() {
  useUrl.value = protocol.value + inputUrl.value;
  const webview = webviewRef.value;
  if (webview) {
    webview.loadURL(useUrl.value);
  }
}

/**
 * 刷新当前页面
 */
function refreshWebview() {
  const webview = webviewRef.value;
  if (webview) {
    webview.reload();
  }
}

/**
 * 后退到上一页
 */
function goBack() {
  const webview = webviewRef.value;
  if (webview && canGoBack.value) {
    webview.goBack();
  }
}

/**
 * 前进到下一页
 */
function goForward() {
  const webview = webviewRef.value;
  if (webview && canGoForward.value) {
    webview.goForward();
  }
}

// ========================================================================================
// 缩放控制函数 (Zoom Control)
// ========================================================================================

/**
 * 设置网页缩放比例
 * 解析缩放值并应用到WebView
 */
function setZoomFactor() {
  const webview = webviewRef.value;
  if (!webview) return;

  ZoomFactor.value = parseFloat(ZoomFactor.value);
  webview.setZoomFactor(ZoomFactor.value);
}

// ========================================================================================
// WebView事件处理函数 (WebView Event Handlers)
// ========================================================================================

/**
 * 处理WebView DOM准备就绪事件
 * 设置初始样式、事件监听器等
 * @param {HTMLElement} webview - WebView DOM元素
 */
function handleWebViewDomReady(webview) {
  // 将当前访问的URL回显到地址框
  const currentUrl = webview.getURL();
  if (currentUrl) {
    // 移除协议头并设置到输入框
    const urlWithoutProtocol = currentUrl.replace(/^https?:\/\//, '');
    inputUrl.value = urlWithoutProtocol;
    // 设置对应的协议
    protocol.value = currentUrl.startsWith('https://') ? 'https://' : 'http://';
  }

  // 延迟注入初始CSS样式
  setTimeout(async () => {
    const cssKey = await webview.insertCSS(`
      * {
        background: ${backgroundColor.value} !important;
      }
    `);
    webview.insertCSS(`
      ::-webkit-scrollbar {
        display: none !important;
      }`)
    injectedCSSKeys.value.add(cssKey);
  }, 500);
}

/**
 * 处理WebView新窗口事件
 * 阻止新窗口打开，在当前WebView中加载链接
 * @param {Event} e - 新窗口事件
 */
function handleNewWindow(e) {
  e.preventDefault();
  const webview = webviewRef.value;
  if (webview) {
    webview.loadURL(e.url);
  }
}

/**
 * 设置WebView事件监听器
 * 包括导航事件、新窗口事件等
 * @param {HTMLElement} webview - WebView DOM元素
 */
function setupWebViewEventListeners(webview) {
  // DOM准备就绪事件
  webview.addEventListener('dom-ready', () => handleWebViewDomReady(webview));

  // 新窗口事件
  webview.addEventListener('new-window', handleNewWindow);

  // 导航相关事件
  webview.addEventListener('did-start-loading', updateNavigationState);
  webview.addEventListener('did-navigate', updateNavigationState);
  webview.addEventListener('did-navigate-in-page', updateNavigationState);
}

// ========================================================================================
// 生命周期钩子 (Lifecycle Hooks)
// ========================================================================================

/**
 * 组件挂载后的初始化
 * 设置WebView事件监听器和IPC通信
 */
onMounted(() => {
  const webview = document.querySelector('webview');
  if (!webview) {
    console.error('WebView元素未找到');
    return;
  }

  // 设置WebView事件监听器
  setupWebViewEventListeners(webview);

  // 设置IPC监听器
  window.electron.ipcRenderer.on('toggle-controls', () => {
    showControls.value = !showControls.value;
  });
});

/**
 * 组件卸载前的清理
 * 移除所有事件监听器
 */
onBeforeUnmount(() => {
  // 移除IPC监听器
  window.electron.ipcRenderer.removeAllListeners('toggle-controls');
});
</script>

<style scoped>
.electron-app {
  width: 100vw;
  height: 100vh;
  display: flex;
  flex-direction: column;
  background-color: transparent;
  position: relative;
}

.opacity-control {
  position: absolute;
  top: 20px;
  left: 20px;
  background: rgba(255, 255, 255, 0.95);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  padding: 20px;
  border-radius: 8px;
  -webkit-app-region: drag;
  max-width: 600px;
}

.hidden-opacity-control {
  padding: 8px;
  top: 0;
  left: 0;
}

.control-panel {
  -webkit-app-region: no-drag;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.form-group {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.form-group label {
  font-size: 14px;
  color: #333;
  font-weight: 500;
}

.url-input-group {
  display: flex;
  gap: 8px;
  align-items: center;
}

.navigation-buttons {
  display: flex;
  gap: 4px;
}

.nav-button {
  padding: 6px 12px;
  border: 1px solid #ddd;
  border-radius: 4px;
  background-color: #fff;
  cursor: pointer;
  transition: all 0.2s;
}

.nav-button:hover:not(:disabled) {
  background-color: #f0f0f0;
}

.nav-button:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.nav-button span {
  font-size: 16px;
  line-height: 1;
}

.protocol-select {
  width: 100px;
  padding: 6px;
  border: 1px solid #ddd;
  border-radius: 4px;
  background-color: #fff;
}

.url-input {
  flex: 1;
  padding: 6px 12px;
  border: 1px solid #ddd;
  border-radius: 4px;
  font-size: 14px;
}

.button-group {
  display: flex;
  gap: 8px;
}

.primary-button,
.secondary-button {
  padding: 6px 12px;
  border-radius: 4px;
  border: none;
  font-size: 14px;
  cursor: pointer;
  transition: all 0.2s;
}

.primary-button {
  background-color: #1890ff;
  color: white;
}

.primary-button:hover {
  background-color: #40a9ff;
}

.secondary-button {
  background-color: #f0f0f0;
  color: #333;
}

.secondary-button:hover {
  background-color: #d9d9d9;
}

.color-input-group {
  display: flex;
  gap: 8px;
  align-items: center;
}

.color-picker {
  width: 40px;
  height: 30px;
  padding: 0;
  border: 1px solid #ddd;
  border-radius: 4px;
}

.range-input-group {
  display: flex;
  gap: 12px;
  align-items: center;
}

.range-slider {
  flex: 1;
  height: 6px;
  -webkit-appearance: none;
  background: #e1e1e1;
  border-radius: 3px;
  outline: none;
}

.range-slider::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 16px;
  height: 16px;
  background: #1890ff;
  border-radius: 50%;
  cursor: pointer;
}

.range-value {
  min-width: 40px;
  font-size: 14px;
  color: #666;
}

.browser-select {
  width: 100%;
  padding: 6px;
  border: 1px solid #ddd;
  border-radius: 4px;
  background-color: #fff;
  font-size: 14px;
}

.ifr {
  width: 100%;
  height: 100%;
  border: 0;
  background: transparent;
}
</style>